#pragma once

#include "server.hpp"

using PtrConnection = std::shared_ptr<Connection>;
class ChatRoom
{
private:
    TcpServer server_;

private:
    void OnConnected(const PtrConnection &conn)
    {
        lg(Info, "[%s:%d]:Go online!!!", conn->ClientIp().c_str(), conn->ClientPort());

        std::string msg = "Server connection successful. You are online!!!";
        conn->Send((void *)msg.c_str(), msg.size());
    }
    void OnMessage(const PtrConnection &conn, Buffer *in_buf)
    {
        // 打印日志
        lg(Info, "[%s:%d]:%s", conn->ClientIp().c_str(), conn->ClientPort(), in_buf->ReadPosition());

        std::string message = in_buf->ReadAsStringAndPop(in_buf->ReadAbleSize());
        std::string echo_string;
        if (message == "GET_ONLINE_COUNT")
        {
            // 如果是获取当前在线人数，则发送特定字符串
            echo_string = "GET_ONLINE_COUNT\n";
            for (auto kv : server_.conns_)
            {
                echo_string += "[";
                echo_string += kv.second->ClientIp();
                echo_string += ":";
                echo_string += std::to_string(kv.second->ClientPort());
                echo_string += "]";

                //本机
                if (kv.second == conn)
                {
                    echo_string += " 本机";
                }
                echo_string += "\n";
            }
            echo_string += "当前在线人数:";
            echo_string += std::to_string(server_.ConnCount());
            return conn->Send((void *)echo_string.c_str(), echo_string.size());
        }
        else
        {
            echo_string += "[";
            echo_string += conn->ClientIp();
            echo_string += ":";
            echo_string += std::to_string(conn->ClientPort());
            echo_string += "] ";
            echo_string += message;
        }

        // 群发
        for (auto kv : server_.conns_)
        {
            if (kv.second == conn)
            {
                std::string copy_string = echo_string;
                copy_string.insert(0, "本机 ");
                kv.second->Send((void *)copy_string.c_str(), copy_string.size());
                continue;
            }
            kv.second->Send((void *)echo_string.c_str(), echo_string.size());
        }
    }
    void OnClosed(const PtrConnection &conn)
    {
        lg(Info, "[%s:%d]:Be offline...", conn->ClientIp().c_str(), conn->ClientPort());
    }

public:
    ChatRoom(int port) : server_(port)
    {
        server_.SetMessageCallBack(std::bind(&ChatRoom::OnMessage, this, std::placeholders::_1, std::placeholders::_2));
        server_.SetConnectedCallBack(std::bind(&ChatRoom::OnConnected, this, std::placeholders::_1));
        server_.SetClosedCallBack(std::bind(&ChatRoom::OnClosed, this, std::placeholders::_1));
        server_.SetThreadCount(2);
        server_.EnableInactiveRelease(60);
    }
    void Start()
    {
        server_.Start();
    }
};